package com.nanbei.a14;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;

/**
 * @ClassDescription:
 * @JdkVersion: 1.8
 * @Author: libs
 * @Created: 2024/11/18 15:53
 */
public class Proxy extends Target {
    private MethodInterceptor methodInterceptor;

    public Proxy() {
    }

    public Proxy(MethodInterceptor methodInterceptor) {
        this.methodInterceptor = methodInterceptor;
    }

    static Method save0;
    static Method save1;
    static Method save2;
    static MethodProxy saveSuper0;
    static MethodProxy saveSuper1;
    static MethodProxy saveSuper2;
    static {
        try {
            save0 = Target.class.getMethod("save");
            save1 = Target.class.getMethod("save", int.class);
            save2 = Target.class.getMethod("save", long.class);
            /**
             * Class c1  目标类型,
             * Class c2  代理类型,
             * String desc  （）表示无参 V表示返回值类型  I：int  J:long,
             * String name1  带增强功能的方法名,
             * String name2  带原始功能的方法名
             */
            saveSuper0 = MethodProxy.create(Target.class,Proxy.class,"()V","save","saveSuper");
            saveSuper1 = MethodProxy.create(Target.class,Proxy.class,"(I)V","save","saveSuper");
            saveSuper2 = MethodProxy.create(Target.class,Proxy.class,"(J)V","save","saveSuper");
        } catch (NoSuchMethodException e) {
            throw new NoSuchMethodError(e.getMessage());
        }
    }
    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 带原始功能的方法
    public void saveSuper() {
        super.save();
    }
    public void saveSuper(int i) {
        super.save(i);
    }
    public void saveSuper(long l) {
        super.save(l);
    }


    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 带增强功能的方法
    @Override
    public void save() {
        try {
            methodInterceptor.intercept(this,save0,new Object[0],saveSuper0);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    @Override
    public void save(int i) {
        try {
            methodInterceptor.intercept(this,save1,new Object[]{i},saveSuper1);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    @Override
    public void save(long l) {
        try {
            methodInterceptor.intercept(this,save2,new Object[]{l},saveSuper2);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }
}
